﻿/*
智能指针
	RAII和智能指针的设计思路
	1.RAII是Resource Acquisition Is Initialization的缩写，他是一种管理资源的类的设计思想，本质是
	  一种利用对象生命周期来管理获取到的动态资源，避免资源泄漏，这里的资源可以是内存、文件指针、
	  网络连接、互斥锁等等。
	  R是资源    A是请求     第一个I：是立即     第二个I：获取到资源立即初始化

	(RAII在获取资源时把资源委托给一个对象)，接着控制对资源的访问，资源在对象的生命周期内始终保持有效，
	最后在对象析构的时候释放资源，这样保障了资源的正常释放，避免资源泄漏问题。

	2.智能指针类除了满足RAII的设计思路，还要方便资源的访问，所以智能指针类还会像迭代器类⼀
	  样，重载 operator*   operator->   operator[] 等运算符，方便访问资源。


boost 
	为C++语言标准库提供扩展一些C++程序库的总称   Boost就是为C++标准化工作提供可供参考的实现
		C++ 98 产生第一个智能指针 auto_ptr
		C++ boost 给出更实用的scoped_ptr 和 shared_ptr 和weak_ptr
		C++ TR1,引入shared_ptr等，但是TR1不是标准版
		C++ 11，引入unique_ptr，shared_ptr和weak_ptr，
		注意：unique_ptr 对应的 boost的 scoped_ptr。并且这些智能指针的实现原理是参考boost中的实现的。



C++ 标准库智能指针的使用    (智能指针是代管资源，模拟指针的行为   访问修改资源)    浅拷贝的析构多次的问题
	#include<memory>
	1.C++标准库中的智能指针都在<memory>这个头文件下，我们包含<memory>就可以是使用了，
	  智能指针有好几种，除了weak_ptr他们都符合RAII和像指针一样访问的行为，原理上而言主要是解
	  决智能指针拷贝时的思路不同。
	2.auto_ptr是C++98时设计出来的智能指针，他的特点是拷贝时把被拷贝对象的资源的（管理权转移）
	  给拷贝对象，这是一个非常糟糕的设计，因为他会导致：被拷贝对象悬空，访问报错的问题，C++11
	  设计出新的智能指针后，强烈建议不要使用auto_ptr。其他 C++11出来之前很多公司也是明令禁止用
	  这个智能指针的。（始终只有一个对象管理这个资源   只会析构一次）

	3.unique_ptr是C++11设计出来的智能指针，他的名字翻译出来是唯一指针，他的特点的(不支持拷
	  贝，只支持移动)。如果不需要拷贝的场景就非常建议使用他。

	4.shared_ptr是C++11设计出来的智能指针，他的名字翻译出来是共享指针，他的特点是(支持拷贝，
	  也支持移动)。如果需要拷贝的场景就需要使用他了。底层是用引用计数的方式实现的。
	
	5.weak_ptr是C++11设计出来的智能指针，他的名字翻译出来是弱指针，他完全不同于上面的智能指
	  针，他不支持RAII，也就意味着不能用它直接管理资源，weak_ptr的产生本质是要解决shared_ptr
	  的一个循环引用导致内存泄漏的问题。
	
	6.智能指针析构时默认是进行delete释放资源，这也就意味着如果不是new出来的资源，交给智能指
	  针管理，析构时就会崩溃。智能指针支持在构造时给一个删除器，所谓删除器本质就是一个可调用
	  对象，这个可调用对象中实现你想要的释放资源的方式，当构造智能指针时，给了定制的删除器，
	  在智能指针析构时就会调用删除器去释放资源。因为new[] 经常使用，所以为了简洁一点，
	  unique_ptr和shared_ptr都特化了一份[]的版本，使用时 unique_ptr<Date[]> up1(newDate[5]);
	  shared_ptr<Date[]> sp1(new Date[5]); 就可以管理new[]的资源。
	
	7.template <class T, class... Args> shared_ptr<T> make_shared (Args&&... args);
	
	8.shared_ptr 除了支持用指向资源的指针构造，还支持 make_shared 用初始化资源对象的值
	  直接构造。
	
	9.shared_ptr 和 unique_ptr 都支持了operator bool的类型转换，如果智能指针对象是一个
	  空对象没有管理资源，则返回false，否则返回true，意味着我们可以直接把智能指针对象给if判断
	  是否为空。
   
   10.shared_ptr 和 unique_ptr 都得构造函数都使用explicit 修饰，防止普通指针隐式类型转换
	  成智能指针对象。

	他们解决拷贝析构多次的问题的思路不同 

*/